//   SPARKDRUMMER'S CHALLENGE: RESCUE At AtariAge 1.0, 4.09.2017 (FestWest 2017 Edition)
//   by Airshack on AtariAge.com, shackel@gmail.com (c) James Shackel
//   13005 West Luchana Drive, Litchfield Park, AZ 85340, 480-221-5741
//   requires XB256 by Harry Wilhelm

		HS = 0 
SCRAA: 	RESTORE :: RANDOMIZE :: OPTION BASE 1:: CALL LINK("CHSETL"):: DISPLAY ERASE ALL
	 
// Variable Assignments 

		// AC = Arena Color
		// BB = Blast Bit/Quit Flag, B = GETCHAR character returns, BR Brick row, 
		// BC = Brick column, BV = Brick Laying Velocity (RATE), BN = BI = Brick Index Counter
		// CP = crash penalty flag, C,C2 = GETCHAR returns, CO = MoJo Hunt COinc, C7 = Coinc with Sprite #7 flag
		// DP = Droping Pallet Flag, DI = Drop Instructions Flag, D1-D4 = tunnel stop displacement
		// DX = Dot Row for terrain build GCHAR, DF = Drop Failures, DS = dot score
		// FC = level foreground color,FR = Frame Reference Number, FU = Fuel Used
		// G = graphic character number (screen2) , G$ = graphic char hex code (screen2)
		// HM = Have Mojo Flag, HS = High Score
		// I = Loop counter, IQ = loop counter for Big MoJo lateral movement 
		// J = Loop counter
		// KV = Key Variable (joystick)
		// LP = terrain low point,LM = Lunar Modules (Ships) Remaining
		// M$ = Message Buffer , M2$ = Screen Shot Storage Strings, MJ1$-Mj$3 = MoJo Hunt Level Screen Image
		// MF = MoJo Level Flag, MS = # of MoJo Steers
		// N = Noise Value, NL = Next Line VREAD Index
		// OD = Orbit Direction, OC = Orbit Column, OF = Orbit Flag, OS = Omega Struck? Flag, OB = Omega Blocks
		// PD = Previous Difficulty
		// QS = Total Score, QH = High Score
		// RF = Refuel Flag/Bit in Maze Level
		// SC = Sparky Column, SR = Sparky Row, SN = Ship # (33-35), S = Scroll Counter for Ship Animation & Scroll Arrows
		// SK = Skill Level(1=HARD,2=MED,3=EASY), SB = Scoreboard, SL = Screen Level, 
		// SV = Status Variable (joystick), SM = Skill multiplier(Hard=3,Med=2,Easy=1)
		// TT(4) = Tunnel Tops, TR(4) = Tunnel Reference, T1$-T4$ = Terrain screen level image, TM(4) = Tunnel Movement
		// TW = Tunnel width, TV = Tunnel Acceleration, TS = Tunnel Speed 
		// VR = velocity row, VC = velocity column, VM = Video Memory Index
 		// WC = Wall Movement counter
 		// XT = active Tunnel, XC = column for XT, XB = Block replacement character
		// YB$ = Yellow Bar String
		

		DIM TT(4), AC(5), DX(32), TM(4), TR(4)     

// Initialize Variables (in case of game restart)
	VR=0 :: VC=0 :: SL=1 :: LM=3 :: I = 0 :: G = 0  :: RF = 0 :: CP = 0:: OB = 0 :: G$ = "0000000000000000"::HM=0::DI=0
	MF = 0:: FR=1:: SN=33:: PD = 15 :: OF = 0 :: OS = 0 :: TW = 4 :: BV = 50 :: BI = 0:: TS = 14 :: TV = 2::DF=0 // tunnel scroll speed slower with higher number
	D1 = 7 :: D2 = 15 :: D3 = 23 :: D4 = 30 :: OC = 3 :: SC = 32 :: SR = 24 ::CB=0	// displacement from walls before they stop scrolling	
	QS = 0:: DS = 0::IQ = 0
	FOR I = 1 to 5:: READ AC(I) :: NEXT I    // Defines the 5 arena colors in sequence	
	

// Character Assignments  --------------------------------------------------------------------------------------------- //

	// SCRAA: Characters Used ( Future games put sprites 96-159, CS9-CS16)
	
// ----- XB includes CS0 (30-31 only) - CS14 -----

	// CS0/32 24-31:	DrkRed/Black
	// 24 - empty black tile
	// 25 - building block1
	// 26 - building block2
	// 27 - building block3
	// 28 - Ship remaining ships


// ----- XB256 includes above sets ---- 

// *** Sprites MUST be between CS1-CS14 via CALL CHAR, Best to use CS9-)

	// CS1 32-29:		DrkYel/Tsp
	// 32 - blank dark space
	// 33 - ship1
	// 34 - ship2
	// 35 - ship3
	// 36 - ship4
	// 37 - ship5
	// 38 - Engine Blast
	// 39 - Orbiter Ship (square window)

	// CS3 48-55:		DrkYel/Tsp
		//48-55 - Numbers 0-7

	//CS4 56-63:		DrkYel/Tsp	
		// 56-57 - Numbers 8 and 9
		// 58-63 - punctuation

	// CS5 64-71		DrkYel/Tsp
		// 64      @
		// 65-71 A-G

	// CS6 72-79		DrkYel/Tsp		
		// H - O

	// CS7 80-87		DrkYel/Tsp
		// P - W

	// CS8 88-95		DrkYel/Tsp
		// 88-90 X-Z
		// 91-95 punctuation

	// CS9 96-103		White/Black
		// 96-99 - Big VAST MoJo four character size
		// 100-103 -  Sparkdrummer Drumroll


	// CS10 104-111		LtBlue/Tsp
		// 104-107 - Bad Omega
		// 108-111 - LOL ship cage

	// CS11 112-119		DrkYel/Black
		// 112-115	- FestWest 2017 Logo
		// 118 - Sparky Jumping Up
		// 119 - Sparky Falling Down


	// CS12 120-127
		// 120-123  -Standard size ship (Magnify 3)
		// 124-127 - Standard size VAST MoJo pallet (Magnify 3)

	// CS13 128-135
		// 128-131 - Omega beard
		// 132-135 - Omega brick 

	// CS14 136-143
		// 136-139 - Omega Eyes
		// 140-143 - Engine Blast (Magnify 3)


// ----- BASIC includes CS15 and CS16, XB stops at CS14

	// CS15 144-151	DkGreen/Tsp
		// 144 - Green cactus
		
	// CS16 152-159
		// 152 - Breadcrumb dot
		// 153 - Right arrow exit
		// 154 - Down arrow exit
		
// ----- XB256 includes below -----

	// CS17 160-167		LtYellow/Tsp

		// 160 - Terrain Block
		// 161 - Terrain Peak
		// 162 - Terrain TLBR
		// 163 - Terrain BLTR

	// CS28 248-255		DkBlue/Tsp
		// 248-252 Airshack Logo
	
	
	FOR I=1 TO 18 :: READ G,G$ :: CALL LINK("CHAR2",G,G$):: NEXT I   // Sets SCRN2 char patterns
	FOR I=1 TO 24 :: READ G,G$ :: CALL CHAR(G,G$):: NEXT I ::DISPLAY ERASE ALL  //  Sprites use SCRN1 patterns in both screens
	
// Character Set Color Assignments & Screen Colors ------------------------------------------------------------- //


	// SCRN1 = normal XB screen (this game makes exclusive use of Screen2)
		
	// SCRN2 = enhanced graphics screen ( initially clear, white/trnspt std char set, dark blue screen )
	
	// "COLOR2" = Changes the color of characters used by Screen2
		
	CALL COLOR(1,11,1)::CALL LINK("COLOR2",0,7,2,2,11,1,3,11,1,4,11,1,5,11,1)   	// Establish Screen2 CharSet colors
	CALL LINK("COLOR2",6,11,1,7,11,1,8,11,1,9,15,2,10,6,1)
	CALL LINK("COLOR2",11,11,2,15,13,1,16,11,1,17,12,1,18,5,1)
	CALL LINK("COLOR2",1,11,1,28,9,1)
	
	// COLORS:	Set 	Color
	//			0		DkRed/Black
	//			1		DkYel,Tsp
	// 			2		DkYel, Tsp
	//			3		White/Tsp
	//			4		LtYel/Tsp
	//			5		DkYel/Tsp
	//			6 		DkYel/Tsp
	//			7		DkYel/Tsp
	//			8 		DkYel/Tsp
	//			9		Gray/Blk
	//			10		LtBlue/Tsp
	//			11		DkYel/Blk
	//			15		DkGrn/Tsp
	//			16		DkYel/Tsp
	//			17		LtYel/Tsp
	//			18		DkBlue/Tsp		
			
// Sprite Assignments

	// #1 = Ship, #2 = Rocket Blast, #3 = Sparkdrummer, #4 = Unassigned, #5 Big Ship on MoJo Hunt Screen,
	// #6 = Omega, #7 = VAST MoJo

	
	CALL SPRITE(#1,33,14,192,256,#2,38,12,192,256) // Engine Blast
	
	DISPLAY ERASE ALL::GOSUB Title_Screen
	GOSUB Level_Pick


Start_Over:	    // returns to here after a crash or Mojo Delivered thus finishing a level

	
	CALL MAGNIFY(1)::FR = 0	:: FU=0 :: WC = 0 :: S = 0::GOSUB Arena_Build 	
	CALL LOCATE(#1,120,1)::GOSUB Count_Down
	GOSUB Joystick_Up
	
//  *********************************************************************************************************
//  *********************************************************************************************************
Main_Loop: 		//   Maze Level Loop - game initially was just this screen
		
		FR = FR+1 :: WC = WC +1 :: S = S + 1 :: CALL LINK("THAW")::IF S < 2 THEN Tunnels_Move   // controls ship & yellow arrows, not tunnels
			GOSUB Ship_Swap  // flip ship tiles every 2 frames/loops
			CALL LINK("SCPXLF",153,1,7):: S = 0	// Scroll yellow arrows also
		
			
		
		Tunnels_Move:	IF WC < TS OR SK = 3 THEN Controller		// when wall counter is less than tunnel speed or not EASY Skill
						
						
					IF CC > D4 THEN Stp_Tunnels		// when ship column trips the wall stop switch
						XT = 4 :: XC = 32 :: XB = 153 :: GOSUB Tunnel_Mover   // XT = active Tunnel, XC = column for XT, XB = Block replacement character
					IF CC > D3 THEN Stp_Tunnels		// tunneler 3
						XT = 3 :: XC = 24 :: XB = 24 :: GOSUB Tunnel_Mover
						// IF SL = 1 THEN Stp_Tunnels
					IF CC > D2 THEN Stp_Tunnels		// tunneler 2
						XT = 2 :: XC = 16 :: GOSUB Tunnel_Mover  
						IF SL = 1 THEN Stp_Tunnels
					IF CC > D1 THEN Stp_Tunnels		// tunneler 1
						XT = 1 :: XC = 8 :: GOSUB Tunnel_Mover
			
					Stp_Tunnels:  WC = 0  // reset the Wall Counter		
									
				// Up = JR = 4, Down = JR = -4, Left = JC = -4, Right = JC = 4, otherwise zeros
				
	Controller: CALL JOYST(1,JC,JR)::VR=VR-JR+1 :: VC=4::IF VR<13 THEN Test_Up
				VR=12 :: GOTO Hide_Blast
	Test_Up:	IF VR> -13 THEN Hide_Blast
                VR=-12
	Hide_Blast: CALL LOCATE(#2,192,256)::CALL MOTION(#1,VR,VC):: VS=(ABS(VR)+22)*100 :: CALL SOUND(30,VS,20) // Animate ship and make tone
	
		CALL LINK("FREEZE"):: CALL POSITION(#1,PR,PC)::IF PR>8 THEN Chk_Bottom :: GOSUB Wall_Contact  // Hits Top
			GOTO Start_Over
			
	Chk_Bottom: IF PR<177 THEN Chk_Start :: GOSUB Wall_Contact  // Hits Bottom
			GOTO Start_Over
			
	Chk_Start: IF PR>176 OR PR<9 THEN Start_Over	// flew off top or bottom of maze	

	Chk_Char: CC=INT((PC+4)/8)+1 :: CR=INT((PR+4)/8)+1::CALL GCHAR(CR,CC+1,C):: CALL GCHAR(CR,CC,C2) 
	
	IF C2<>25 THEN Dot_Drop  // If not hitting a wall block then leave a breadcrumb dot
	
	C = 25		// DS = dot score
	
	Dot_Drop: CALL VCHAR(CR,CC,152)::QS = QS +2*SM:: GOSUB Update_Score	// Score increases with each dot
	
	IF C=24 THEN Chk_Strt :: GOSUB Wall_Contact  	// Encountered Wall or Exit Arrow, Char 24 = empty black tile
	
	IF RF = 0 THEN Chk_Strt   // No Refuel Flag 
	
	// Else we progress to MoJo and Airdrop Levels
	CALL LOCATE(#1,192,256)::CALL LOCATE(#3,192,256)::GOSUB MoJo_Drop
	
	Chk_Strt:  IF C<>24 THEN Start_Over		// you've hit something
	
	IF JR<>4 THEN Main_Loop  // If joystick_up not pressed, glide.
	
	
		CALL POSITION(#1,PR,PC)::CALL LOCATE(#2,PR+8,PC)::CALL SOUND(-200,-5,10):: FU=FU+1 // Fire Thrusters w Joystick_up
	
	
GOTO Main_Loop   

// -----------------------------------------------------------------------------------------------------------------


Title_Screen:

			
	
		 	CALL MAGNIFY(3)::CALL LINK("SCRN2"):: DISPLAY ERASE ALL :: CALL LINK("SCREEN",2) // screen2 black 
			CALL LINK("COLOR2",0,5,2,11,5,2)::CALL HCHAR(4,4,25,26)::CALL HCHAR(11,4,25,26)
			CALL HCHAR(22,4,25,26)::CALL VCHAR(4,3,25,19)::CALL VCHAR(12,9,25,4)::CALL VCHAR(12,16,25,2)
			CALL VCHAR(12,23,25,6)::CALL VCHAR(19,9,25,3)::CALL VCHAR(17,16,25,5)::CALL VCHAR(21,23,25,1)
			
			CALL SPRITE(#1,120,14,121,89,#6,104,6,137,193,#7,68,12,9,17,#8,68,12,9,217,#17,112,12,177,241))  // VAST Mojo2 
			
			DISPLAY AT(6,3):"SPARKDRUMMER'S CHALLENGE"::DISPLAY AT(9,6):"RESCUE AT ATARIAGE"::CALL VCHAR(4,29,25,19)
			
			FOR I = 248 TO 252:: CALL VCHAR(2,I-234,I,1)::NEXT I :: FR = 0  
			DISPLAY AT(24,5):"JOYSTICK UP TO PLAY"::CALL LINK("DELAY",1000)  // Assures KeyLock not Depressed
			Joy_Push: CALL JOYST(1,JC,JR):: FR = FR + 1   // Up = JR = 4, Down = JR = -4, Left = JC = -4, Right = JC = 4, otherwise zeros
			
				IF FR < 5 THEN Tst_Joy
					GOSUB Block_Anim8
						
			Tst_Joy: IF JR<4 THEN Joy_Push
			CALL LOCATE(#1,192,256)::CALL DELSPRITE(#6,#7,#8,#17)::CALL MAGNIFY(1)::FR = 1
			
RETURN  
	
// ----------------------------------------------------------------------------------------------------------------
	

	
	Arena_Build:  

		FC = AC(SL)::CALL LINK("COLOR2", 0, FC, 2 )::DISPLAY ERASE ALL :: CALL LINK("SCREEN", 2) 
		CALL HCHAR(1,1,24,768)::CALL HCHAR(23,1,25,32):: CALL VCHAR(17,1,25,7)::CALL HCHAR(24,1,28,LM-1)	// place extra ships
		CALL HCHAR(1,1,25,32)::CALL VCHAR(2,1,25,11)::GOSUB Update_Score
		
		IF CB=1 THEN No_New_Arena     // set CB = 0 for continued games
		
		// Otherwise define new-level with tunnels and assure increasing difficulty

	
	Tunnel_Def: FOR I = 1 TO 4 :: TT(I)=INT(RND*18)+2 :: TR(I) = TT(I) 
					IF TR(I) < 12 THEN Wall_Down
						TM(I) = 1 :: GOTO Nxt_I
					Wall_Down: TM(I) = -1
					Nxt_I: NEXT I
				
	No_New_Arena:     CB=0 // Reset Circuit Breaker allowing for difficult maze to only cost max two lives
	
	// Adjust Tunnel Width from 4 to 3 wide above level 2
		
		IF SL <3 OR SK >1 THEN Tun_Draw   // Narrow Tunnels above level2 if HARD skill level
				TW = 3 
		Tun_Draw: CALL VCHAR(2,8,25,22):: CALL VCHAR(2,16,25,22):: CALL VCHAR(2,24,25,22):: CALL VCHAR(2,32,25,22)
		CALL VCHAR(TT(1),8,24,TW):: CALL VCHAR(TT(2),16,24,TW):: CALL VCHAR(TT(3),24,24,TW)
		CALL VCHAR(TT(4),32,24,TW):: CALL VCHAR(TT(4),32,153,TW)::VR=0 :: VC=0
	
			CALL LOCATE(#1,120,1)::CALL LINK("VREAD",352,96, M$)   // COPY THREE ROWS OF SCREEN (11-14)
			IF CP = 0 THEN Lvl_Msg
					// returning from a crash on another screen
					DISPLAY AT(12,9):"PENALTY MAZE":: GOSUB Update_Score
					GOTO J_Up
			
			Lvl_Msg: IF SL>1 THEN Try_Two
				 M2$ = " LEVEL I":: GOTO J_Upp
			 Try_Two: IF SL>2 THEN Try_Three
				 M2$ = " LEVEL II":: GOTO J_Upp
				Try_Three: IF SL>3 THEN Try_Four
				 M2$ = " LEVEL III":: GOTO J_Upp
			 Try_Four: IF SL>4 THEN Try_Five 
				 M2$ = " LEVEL IV":: GOTO J_Upp
			 Try_Five: M2$ = "FINAL LEVEL"
			
			J_Upp:	DISPLAY AT(12,10)SIZE(11):M2$
			
			J_Up: DISPLAY AT(14,5):"JOYSTICK UP TO BEGIN"::CP = 0::GOSUB Joystick_Up
			CALL LINK("DELAY", 2000)::CALL LINK("VWRITE",352, M$)     // RESTORE THREE SCREEN ROWS	
				
	RETURN  
// --------------------------------------------------------------------------------------------------------

Tunnel_Mover:
		// XT = Active Tunnel, XC = Column for XT, XB = Block Replacement Character 25 or 153
		// Blank Black Tile 24, Building Block Red 25, Yellow Rt Arrow = 153
			IF TM(XT) = -1 THEN Tunnel_Up  
			
			// Tunnel moves down
				IF TR(XT) < 19 THEN Plot_Down
					TM(XT) = -1 :: GOTO Done_Movin   // reverse tunnel movement direction at the bottom
				Plot_Down: CALL VCHAR(TR(XT),XC,25):: CALL VCHAR(TR(XT)+TW,XC,XB)::TR(XT) = TR(XT)+1 ::GOTO Done_Movin
				
			// Move(tunnel moves Up
			Tunnel_Up: IF TR(XT) > 2 THEN Plot_Up
				TM(XT) = 1 :: GOTO Done_Movin  // reverse tunnel movement direction at the top
			Plot_Up: CALL VCHAR(TR(XT),XC,XB)::CALL VCHAR(TR(XT)+TW,XC,25,1)::TR(XT) = TR(XT)-1
			
			// TM = Tunnel Movement score bonus 
			Done_Movin: QS=QS+10*SM::GOSUB Update_Score 
			RETURN 

// --------------------------------------------------------------------------------------------------------	

	
Crash_Ship:		// Maze level crashes

		CALL COLOR(#1,11)::CB=1::CALL LINK("CHAR2",25,"C3C324181824C3C3"):: CALL MOTION(#1,0,0)::CALL LINK("THAW")
		Crash_Action:	
			FOR I=33 TO 37 ::CALL MOTION(#1,(120-PR)*49/100, (1-PC)*49/100) // Sends ship hurtling towards launchpad located at 120,1
				K = I*10::CALL PATTERN(#1,I):: CALL SOUND(40,-8,0,110,5,698,10,K,0):: CALL LINK("FREEZE")
				CALL POSITION(#1,PR,PC)::CALL LINK("THAW")::NEXT I::CALL LINK("FREEZE")
			// CALL POSITION(#1,PR,PC) :: IF ABS(120-PR) >8 OR ABS(1-PC) >8 THEN Crash_Action
				CALL DISTANCE(#1,120,1,I):: IF I > 64 THEN Crash_Action
			CALL MOTION(#1,0,0)::CALL LINK("FREEZE")::CALL LOCATE(#1,120,1)::CALL PATTERN(#1,33)::CALL LINK("CHAR2",25,"7EA5C38181C3A57E")
		

		FU = 0 ::T = 0::LM=LM-1 :: IF LM = 0 Then Ender
		CALL COLOR(#1,14)::RF=0 // Prep new ship
		FOR I = 1 to 4::TT(I) = TR(I)::IF TR(I) < 12 THEN Wall_Down2
					TM(I) = 1 :: GOTO Nxt_I2
			Wall_Down2: TM(I) = -1			
		Nxt_I2: NEXT I
		QS=QS-200*(SM^2)::GOSUB Update_Score
RETURN
// -------------------------------------------------------------------------------------------------------------




Wall_Contact:
	
		// Ship has hit a wall section - Barrier 25(bad) or EXIT 153(good)

		
		VR=0 :: VC=0 :: JR=0 :: JC=0  // Reset ship parameters
		
		IF C=153 THEN Refuel  // Ship reaches the maze exit
		
		// Else CRASH
		GOSUB Crash_Ship
		IF LM > 0 THEN Short_Pause :: GOTO Ender // Game over if out of ships
		
		
Refuel: RF = 1::CALL LOCATE(#1,192,256)::CALL LINK("VREAD",128, 32, M$)   // COPY THREE LINES OF ARENA
			
			IF SL>1 THEN Try_Two2
				DISPLAY AT(5,12):"LEVEL I":: GOTO J_Up2
			Try_Two2: IF SL>2 THEN Try_Three2
				DISPLAY AT(5,11):"LEVEL II":: GOTO J_Up2
			Try_Three2: IF SL>3 THEN Try_Four2
				DISPLAY AT(5,11):"LEVEL III":: GOTO J_Up2
			Try_Four2: IF SL>4 THEN Try_Five2
				DISPLAY AT(5,11):"LEVEL IV":: GOTO J_Up2
			Try_Five2: DISPLAY AT(5,9):"FINAL LEVEL V"
			
			J_Up2: CALL LINK("DELAY",1000)::CALL LINK("VWRITE",128,M$)::DISPLAY AT(5,3):"MAZE NAVIGATION COMPLETE"
		
			
			QS = QS +200*SM::GOSUB Update_Score
			
			
			
			CALL LINK("DELAY",2000)::CALL LINK("VWRITE",128,M$)::GOSUB Build_Terrain   // and Position Sparky
		
		CALL SPRITE(#1,33,14,120,1):: CALL LINK("THAW") // Reset Lander position and motion
		
		IF MF = 1 THEN Launch
		CALL LINK("VREAD",128,32, M$)   // COPY LINE FIVE
			DISPLAY AT(5,5):"SPARKDRUMMER SIGHTED":: CALL LINK("DELAY",1000):: CALL LINK("VWRITE",128, M$)
			DISPLAY AT(5,3):"INITIATE LAUNCH SEQUENCE" :: CALL LINK("DELAY",1000)::CALL LINK("VWRITE",128, M$)
			
		Launch: GOSUB Launch_Seq   	// Ship launches and allows for game pause in orbit
		
	Short_Pause:  CALL LINK("DELAY",100)   // Added here for logic flow skipping refuel
	
RETURN  //  ****************************************************************************************************

Build_Terrain:
	
	DX(1)=17::SR = 1 		// establishes ship platform and initiates Sparky Row variable 
	FOR LC = 2 to 31::FOR LR = 2 TO 22::CALL GCHAR(LR,LC,B)::IF B = 152 THEN Found_Dot	// scan down column looking for dot
		NEXT LR
			DX(LC) = DX(LC-1):: GOTO SparkRow	// no dot found in this column so use last column's value
		Found_Dot: DX(LC) = LR 
			IF DX(LC) < DX(LC-1)+4 THEN SparkyRow
			DX(LC) = DX(LC)-4		// remove large dropoffs in terrain
	SparkyRow: IF SR > DX(LC)-1 THEN New_Column		// Sparky Row is lower than current dot so dont reset SR
			  IF SR = DX(LC)-1 THEN Shift_Left
				SR = DX(LC) - 1	:: SC = LC:: GOTO New_Column			// Sparky Row is set to one row above the latest/lowest dot's elevation
			Shift_Left: SR=DX(LC)-1::SC=LC
		New_Column: NEXT LC	
	
	FOR I = 2 TO 31:: DX(I) = DX(I)+(21-SR)::NEXT I::SR = SR+(21-SR):: DX(32) = DX(31)	// lowers all terrain-tops,lowest is row 22, Sparky 21
			
	// Draw Terrain based on Dot elevation points

	CALL VCHAR(DX(1),1,160,25-DX(1)) :: CALL VCHAR(1,1,24,DX(1)-1) // draw column one 

	FOR LC = 2 TO 31 :: CALL VCHAR(DX(LC),LC,160,25-DX(LC))::CALL VCHAR(1,LC,24,DX(LC)-1)   // draw col of dirt
		IF DX(LC) = 22 THEN Draw_Flat
		IF DX(LC-1) <= DX(LC) THEN Chk_C2		// Peak or BLTR 	
			IF DX(LC+1) >  DX(LC) THEN Draw_Peak
				GOTO Draw_TLBR
		Chk_C2: IF DX(LC-1) = DX(LC) AND DX(LC+1) = DX(LC) THEN Draw_Flat
				IF DX(LC-1) < DX(LC) AND DX(LC+1) < DX(LC) THEN Draw_Flat	
					B = 162:: GOTO Draw_Top		
		
		// Terrain Characters: Block/Flat (160), Peak(161), TLBR(162), BLTR(163)			
		Draw_Peak: B=161::GOTO Draw_Top	
		Draw_TLBR: B=163::GOTO Draw_Top	
		Draw_Flat: B=160::GOTO Draw_Top		
	
		Draw_Top: CALL HCHAR(DX(LC), LC, B)::IF DX(LC-1) <> DX(LC) OR DX(LC) <> DX(LC+1) THEN Adv_Col
			CALL HCHAR(DX(LC)-1,LC,144)
		Adv_Col: NEXT LC
		
		CALL VCHAR(DX(32),32,160,25-DX(32)) :: CALL VCHAR(1,32,24,DX(32)-1)		// draw column 32
		
		CALL MOTION(#1,0,0)::CALL LOCATE(#1,120,1)   // Put Lander back on pad
		CALL LOCATE(#2,192,256)  // jet blast hidden
		
	// Camp Sparkdrummer on Terrain
			CALL HCHAR(SR,SC,24)::SC = SC*8-7::SR=(SR)*8-7::CALL SPRITE(#3,40,15,SR,SC)::GOSUB Sparky_Anim8
		GOSUB Update_Score	
RETURN			

 
  //  ************************************************************************************************



Ship_Swap:
		SN = SN+1:: IF SN<38 THEN Swap  	// Spin ship with CHARs 33-37
		SN = 33
	Swap: CALL PATTERN(#1,SN)
RETURN


Sparky_Anim8:
		FOR I =1 to 5::FOR J=40 to 43::CALL PATTERN(#3,J)::CALL SOUND(80,-8,10,110,10,698,10,I*J*50,10)::NEXT J::NEXT I
		CALL PATTERN(#3,40)::RETURN			




Block_Anim8:
		M$ = "7E8199A5A599837E"::CALL LINK("CHAR2",25,M$):: CALL LINK("DELAY",100)::  M$= "7E8181999981817E" 
		CALL LINK("CHAR2",25,M$):: CALL LINK("DELAY",100):: M$ = "7EA5C38181C3A57E" ::CALL LINK("CHAR2",25,M$)::RETURN 
		

	
Fire_Button: CALL KEY(1,KV,SV) :: IF SV=0 THEN Fire_Button  // 1 = pressed, 0 = no, -1 = held
	RETURN  //  *********************************************************************************************

//  -----------------------------------------------------------------------------------------------------------



	
Keypress: CALL KEY(0,KX,SX) :: IF SX = 0 THEN Keypress
RETURN  //  *********************************************************************************************



//  ---------------------------------------------------------------------------------------------------------------	
Joystick_Up: CALL JOYST(1,JC,JR):: IF JR<4 THEN Joystick_Up 
RETURN	//  ********************************************************************************************
	
	//  ---------------------------------------------------------------------------------------------------------------	

Level_Pick: 	// Up = JR = 4, Down = JR = -4, Left = JC = -4, Right = JC = 4, otherwise zeros
		DISPLAY ERASE ALL :: SK = 1 // screen1 black 
			
			DISPLAY AT(5,6):"SELECT SKILL LEVEL"::DISPLAY AT(9,2):"TURSIAN GRANDMASTER (HARD)"::DISPLAY AT(11,2):"SENIOR FALCONER (MEDIUM)"
			DISPLAY AT(13,2):"SINPHALTIMYSTIC (EASY)"::CALL LINK("DELAY",1000)::DISPLAY AT(20,4):"PRESS BUTTON TO BEGIN"
			CALL LOCATE(#1,65,8)
		Selection: CALL JOYST(1,JC,JR):: CALL KEY(1,KX,SX):: GOSUB Ship_Swap
			IF JR=0 AND SX=0 THEN Selection
				IF KX = 18 THEN Report
				IF JR = 4 THEN Upper
				
				IF JR = -4 THEN Downer
				IF JR = 0 THEN Selection	
				
				Upper: SK=SK-1::IF SK > O THEN Move_Select
						SK = 1::GOTO Selection
				Downer: SK = SK+1::IF SK <4 THEN Move_Select
						SK = 3:: GOTO Selection
						
				Move_Select: CALL LOCATE(#1,(7 + (SK*2))*8-7,8)::CALL SOUND(100,1100,0)::CALL LINK("DELAY",100)::GOTO Selection
				
					
				Report: CALL LOCATE(#1,192,256)::DISPLAY ERASE ALL
					IF SK>1 THEN Chk_SF 
						M$="TURSIAN GRANDMASTER (HARD)":: BV = 50::GOTO Notify  // BV = Rate bricks toss
					Chk_SF: IF SK>2 THEN Assign_SM
						M$="SENIOR FALCONER   (MEDIUM)":: BV = 60:: GOTO Notify
					Assign_SM:  M$="SINPHALTIMYSTIC     (EASY)"::BV = 80
					
				
				Notify: SM=ABS(SK-4)::DISPLAY AT(12,2):M$::CALL LINK("DELAY",2000)::DISPLAY ERASE ALL::RETURN
						
	
	
Launch_Seq:  // Puts orbiter into orbit over terrain
		FR = 1::BB = 0:: OF = 1::HM=0::GOSUB Terrain_Copy
		CALL LOCATE(#3,SR,SC)::CALL LINK("THAW")::CALL MOTION(#1,-8,2) :: CALL SOUND(1300,-5,5)
		CALL VCHAR(17,1,24,6)		// erase launch platform
		Ascent: CALL POSITION(#1,PR,PC)
		
		IF PR< 116 THEN Anim8    // controls blast tile duration
		   CALL LOCATE(#2,PR+9,PC)::CALL MOTION(#2,-8,2)  // Climbing into Orbit loop
		Anim8: GOSUB Ship_Swap
		FR = FR+1 :: If PR>70 THEN Chk_Ascent
			CALL LOCATE(#2,192,256)::CALL MOTION(#2,0,0)::BB=1
		Chk_Ascent: If PR>16 THEN Ascent
		CALL LINK("FREEZE"):: CALL POSITION(#1,PR,PC) :: CALL LOCATE(#1,17,PC) :: CALL LINK("THAW") // Set to row #3
		CALL LOCATE(#2,192,256)::CALL MOTION(#1,0,8)::CALL PATTERN(#1,39)  // established orbit
		
		IF MF = 1 THEN Go_Hunt	// MF = Mojo Level Flag (been there before in this game)
		
		CALL LINK("VREAD",128,32,M$)::DISPLAY AT(5,7):"ORBIT ESTABLISHED"::CALL LINK("DELAY",1000):: CALL LINK("VWRITE",128,M$)
		
		CALL LINK("VREAD",128,32,M$)::DISPLAY AT(5,4):"VAST MOJO READINGS LOW"
		CALL LINK("DELAY",1500)::DISPLAY AT(5,1):"MANEUVER UP TO COLLECT MOJO"
		CALL LINK("DELAY",1500)::DISPLAY AT(5,1):"JOYSTICK BUTTON = AIRBRAKE "::CALL LINK("DELAY",1500)::CALL LINK("VWRITE",128,M$)
				
		Go_Hunt: CALL JOYST(1,JC,JR):: IF JR=4 THEN Hunter
			I = I +1 :: IF I < 20 OR SK = 3 THEN Go_Hunt		// deduct points for orbit delays every 20 loops
			QS = QS - 1:: I=0:: GOSUB Update_Score
			GOTO Go_Hunt
		Hunter: CALL MOTION(#1,0,0)::MF = 1:: GOTO MoJo_Hunt
			

			
	RETURN  //  *******************************************************************************************************

Count_Down:		// allows for breathing room between rounds

		CALL LINK("VREAD",128,32,M$)::DISPLAY AT(5,11)SIZE(9):"GET READY" 
		// IF TT(3) <6 THEN Del1
		// CALL VCHAR(5,24,25,1)
			
		CALL LINK("DELAY",2000):: CALL LINK("VWRITE",128,M$)
		
		
	RETURN  //  *********************************************************************************************************			

Update_Score: IF QS > 0 THEN Show_Score
		QS = 0
		Show_Score: DISPLAY AT(24,23) SIZE(6):QS :: RETURN
	
Terrain_Copy:

		// Puts copy of screen image into T1-T4$ (four panels of six rows) and hides Sparkdrummer
		
		// VDP Address = (Row-1)*32 + Column-1
		CALL LINK("VREAD",0,192,T1$,192,192,T2$,384,192,T3$,576,192,T4$)::CALL POSITION(#3,SR,SC)::CALL LOCATE(#3,192,256)    // locate and hide Sparkdrummer 
	RETURN	
	
Terrain_Paste:
		
		// Restores the MoJo Drop Terrain (Four panels of six rows) Screen and Sperkdrummer
		// VDP Address = (Row-1)*32 + Column-1
		CALL LINK("VWRITE",0,T1$,192,T2$,384,T3$,576,T4$)::CALL LOCATE(#3,SR,SC)
	RETURN		

Draw_Hunt_Arena1:		// draw basic Level 1 MoJo Hunt Arena w tracks for Omega and moving MoJo
		DR = 9 :: VC = 8::CALL HCHAR(1,1,24,768)    // Fills screen blank boxes
		CALL HCHAR(1,1,25,32)::CALL HCHAR(22,1,25,4)::CALL HCHAR(22,29,25,4)::CALL HCHAR(23,1,25,9)
		CALL HCHAR(4,1,25,3)::CALL HCHAR(4,29,25,4)::CALL VCHAR(7,1,25,13)::CALL VCHAR(7,32,25,13)
		CALL HCHAR(19,2,25,3)::CALL HCHAR(19,29,25,3)::CALL HCHAR(7,2,25,3)::CALL HCHAR(23,24,25,9)
		CALL HCHAR(7,29,25,3)::CALL HCHAR(9,11,25,12)
		CALL VCHAR(2,4,25,3)::CALL VCHAR(2,29,25,3)
		
	RETURN	
	
Draw_Hunt_Arena2:		// add middle box and two side box obstructions
		GOSUB Draw_Hunt_Arena1
		CALL VCHAR(9,10,25,6)::CALL VCHAR(9,23,25,6)::CALL HCHAR(14,11,25,12)
		IF SK >2 THEN DoneDHA2
		CALL VCHAR(8,4,25,11)::CALL VCHAR(8,29,25,11)
		DoneDHA2: RETURN
		
	
Draw_Hunt_Arena3:		// add a top bar obstruction
	GOSUB Draw_Hunt_Arena2
	IF SK > 2 THEN DoneDHA3
	CALL HCHAR(3,5,25,24)
	DoneDHA3: RETURN
		

	
Draw_Hunt_Arena4:		// add two bottom bar obstruction
	GOSUB Draw_Hunt_Arena3
	IF SK >1 THEN DoneDHA4
	CALL HCHAR(15,13,25,8)
	DoneDHA4: RETURN
		
	
Draw_Hunt_Arena5:		// Right side blocker wall
	GOSUB Draw_Hunt_Arena4
	IF SK>1 THEN DoneDHA5
	CALL HCHAR(11,24,25,5)
	DoneDHA5: RETURN
		
	RETURN	

	
		
MoJo_Hunt:

		// Sprite 5 = Ship(4Chars), 10 = Omega, 7 = VAST Mojo, 9 = Omega Beard, 8 = Omega Eyes, 6 = Engine Blast
		
		CALL MOTION(#1,0,0)::CALL LOCATE(#1,192,256) :: GOSUB Terrain_Copy 	// copy mojo drop screen terrain
		
		
		IF SL >1 THEN Chk_DHA2
			GOSUB Draw_Hunt_Arena1
			GOTO Reframe
		Chk_DHA2: IF SL>2 THEN Chk_DHA3
			GOSUB Draw_Hunt_Arena2
			GOTO Reframe
		Chk_DHA3: IF SL>3 THEN Chk_DHA4
			GOSUB Draw_Hunt_Arena3
			GOTO Reframe
		Chk_DHA4: IF SL>4 THEN DHA5
			GOSUB Draw_Hunt_Arena4
			GOTO Reframe
		DHA5: GOSUB Draw_Hunt_Arena5
		
		Reframe: FR = 0:: FU =0 :: S = 0 :: OB = 0 :: I=0::GOSUB Update_Score
		
		IF SL > 1 OR MF = 1 THEN Clear_Delay 
		CALL LINK("VREAD",352,32,M$)::DISPLAY AT(12,5)SIZE(22):"TIP: BUTTON = AIRBRAKE"::CALL LINK("DELAY",2000)
		CALL LINK("VWRITE",352,M$)
		
		Clear_Delay: MF = 1:: CALL LINK("DELAY",1000)::VR=-4::VC = 0
	
		CALL MAGNIFY(3):: CALL LOCATE(#1,192,256):: CALL LINK("FREEZE")
		CALL SPRITE(#5,120,14,160,128,#10,104,6,152,1,0,10,#6,140,12,192,256,#9,128,1,152,1,0,10)
		CALL SPRITE(#8,136,1,152,1,0,10)::CALL SPRITE(#7,68,12,33,240,0,-6)::CALL LINK("THAW")
		
			
	MoJo_Loop:   // flying around the MoJo hunt screen
	
		FR = FR+1  :: S = S + 1::IQ=IQ+1::CALL LINK("THAW") :: IF S < 2 THEN Joy_MH
								CALL LINK("SCPXUP",154,1,7) :: S = 0
	
		Joy_MH: CALL JOYST(1,JC,JR) :: CALL KEY(1,KX,SX) // changed max speeds to 12 from 8
				// JOYSTICK: Up = JR = 4, Down = JR = -4, Left = JC = -4, Right = JC = 4, otherwise zeros
			IF KX <> 18 THEN Chk_Joyst
				VR=VR/2::VC = VC/2:: GOTO Animate
			Chk_Joyst: IF JC = 0 AND JR = 0 THEN Animate	
			VR=VR + 1- JR :: VC=VC+INT(JC/2)
				
		 Test_Dn2:	IF VR<9 THEN Test_Up2
							VR=8
		 Test_Up2:	IF VR> -14 THEN Test_L
							VR=-13			
		 Test_L:	IF VC<9 THEN Test_R
							VC=8	
		 Test_R:	IF VC>-9 THEN Animate
							VC = -8
	
					
		Animate:	CALL LINK("FREEZE")::CALL MOTION(#5,VR,VC)::IF HM=0 THEN Soundoff
						CALL MOTION(#7,VR,VC)
					Soundoff: CALL LINK("THAW") :: VS=(ABS(VR)+22)*10 :: CALL SOUND(10,VS,25) // Move ship 
										
					IF JR <> 4 THEN Skip_Thrust		//JR of  4 = Joystick up 
						
						CALL LINK("FREEZE")::CALL POSITION(#5,PR,PC)
						CALL LOCATE(#6,PR,PC)::CALL MOTION(#6,VR,VC)::CALL LINK("THAW")::CALL SOUND(-200,-5,10) // Fire Thrusters w Joystick_up
						CALL MOTION(#6,0,0) :: CALL LINK("DELAY", 50) :: CALL LOCATE(#6,192,256):: FU = FU + 1
						
											
						IF FU <> 5 THEN Skip_Thrust                 
							CALL COLOR(#9,15, #8,10) // make evilness appear
							CALL SOUND(50,131,5,132,6,133,7):: CALL SOUND(25,147,5,148,6,149,7):: CALL SOUND(37,156,5,157,6,158,7)
							CALL SOUND(50,131,5,132,6,133,7):: FOR FI=1 TO 4 :: CALL SOUND(8,185,5,186,6):: CALL SOUND(8,175,5,176,6):: NEXT FI
							CALL SOUND(-25,185,5,186,6,187,7)
						    
	
					Skip_Thrust: // CALL LINK("THAW")  
					
							IF PR>8 THEN Chk_Rtn_Drop  // needless sound test
							CALL SPRITE(#7,68,12,81,128)   // restore VAST MoJo
							GOSUB MoJo_Crash  // Hits Top row of blocks
							GOTO Start_Over  // Returns to the beginning of the level, needing to redo maze screen
		
		Chk_Rtn_Drop: CALL POSITION(#5,PR,PC):: IF PR<184 THEN Stay_Here  
		
			CALL LINK("FREEZE"):: CALL DELSPRITE(#5,#6,#8,#9,#10)
			
			IF HM = 1 THEN GOSUB MoJo_Drop
			
				CALL DELSPRITE(#7)::GOSUB MoJo_Drop  // Else Returns to MoJo drop screen
	
		Stay_Here: CC=INT((PC+4)/8)+1 :: CR=INT((PR+4)/8)+1::CALL LINK("FREEZE")::IF CR >24 THEN MoJo_Drop
					IF CC <33 THEN Test_Space
						CC = 1 
					Test_Space: CALL GCHAR(CR,CC,C) :: IF CR = 24 THEN Chk_Crash	// Skips unnecessary C2 GCHAR
					CALL GCHAR(CR+1,CC,C2) :: CALL LINK("THAW")
					
				Chk_Crash: If C = 24 AND C2 = 24 THEN Fly_On  // The bottom of the character is not off screen
						IF C=154 OR C2 = 154 THEN MoJo_Drop	// your at a doorway w yellow arrows
						GOSUB MoJo_Crash
						HM=0::OS=0::GOTO Start_Over
					
					Fly_On: IF HM = 1 THEN Omega_Chk 
						CALL COINC(#5,#7,8,C7):: IF C7 = 0 THEN Omega_Chk   // Did it touch VAST MoJo source?
						CALL LINK("FREEZE")
						CALL POSITION (#5,PR,PC):: CALL LOCATE(#7,PR,PC)::CALL PATTERN(#7,124)::CALL MOTION(#7,VR,VC):: HM=1
						CALL HCHAR(24,1,25,32) :: CALL HCHAR(24,11,154,10)::SY = PR::SX=PC	// Draw bottom doorway
					GOTO MoJo_Loop

				Omega_Chk: CALL COINC(#5,#10,8,C6)::IF C6 = 0 THEN Hurler    // didnt hit Omega
						IF OS = 1 THEN MoJo_Loop
						CALL LINK("FREEZE")::CALL LINK("VREAD",192,32,M$)  // Copy Line Five
						IF HM=1 THEN Stealer
								CALL POSITION(#10,PR,PC)::CALL LOCATE(#5,PR+16,PC+5)
								DISPLAY AT(7,3)SIZE(24):"YOU'RE YESTERDAY'S NEWS!"::CALL LINK("DELAY",2000):: OS = 1::GOTO Bummer
						Stealer: DISPLAY AT(7,6):"THAT'S OMEGA'S MOJO!":: OS = 1::HM=0
							CALL POSITION(#10,PR,PC)::CALL PATTERN(#7,68)::CALL LOCATE(#7,PR+16,PC)::CALL LINK("DELAY",2000)
							Bummer: CALL SOUND(500,131,5,132,6,133,7):: CALL SOUND(250,147,5,148,6,149,7):: CALL SOUND(375,156,5,157,6,158,7)
							CALL SOUND(500,131,5,132,6,133,7):: FOR FI=1 TO 4 :: CALL SOUND(75,185,5,186,6):: CALL SOUND(75,175,5,176,6):: NEXT FI
							CALL SOUND(-250,185,5,186,6,187,7)::CALL LINK("VWRITE",192,M$)
							QS = QS-200*(SM^2):: GOSUB Update_Score
						LM=LM-1::HM=0::OS=0::OB = 0::CALL DELSPRITE(#5,#6,#7,#8,#9,#10)::DISPLAY ERASE ALL  // lose one ship
						IF LM = 0 THEN Ender	// game over if no more ships
					GOTO Start_Over
					
				Hurler: IF HM = 0 OR OB >11 THEN MoJo_Shift	// only hurl bricks if you have MoJo, only toss 10 bricks
					IF OB = 10 THEN Brick_Ship
					BI = BI +1 ::	IF BI < BV THEN GOTO MoJo_Loop	
							BI = 0 		//	then Bad Omega tosses bricks to close the exit
		
						CALL LINK("FREEZE") :: CALL MOTION(#5,VR/2,VC/2,#7,VR/2,VC/2):: VR = 0 :: VC = 0
						OB = OB +1::BC = (OB + 10)*8 - 7::CALL POSITION(#10,PR,PC)::PR=PR+16::PC = PC +4 :: IF PC < 257 THEN Make_Brick
						PC = 256
					Make_Brick: CALL SPRITE(#4,132,FC,PR,PC,(185-PR)*49/100,(BC-PC)*49/100):: CALL LINK("THAW")	// Flying Brick
							For I = 1 TO 2:: CALL SOUND(100,880,5,890,6):: CALL SOUND(100,880,10,660,11):: CALL SOUND(100,670,16,660,15):: NEXT I
							CALL MOTION(#4,0,0):: CALL LINK("FREEZE") ::OX=PC::OY=PR::CALL POSITION(#4,PR,PC)::CALL LINK("THAW")
						
			
							CALL DELSPRITE (#4)::CALL MOTION(#5,VR,VC,#7,VR,VC)::CALL VCHAR(24,10+OB,25)::QS = QS - 10*(SM^2)
							GOSUB Update_Score
							IF SX < OX THEN Pivot_Left
								CALL MOTION(#8,0,8,#9,0,8,#10,0,8)::GOTO MoJo_Loop
							Pivot_Left: CALL MOTION(#8,0,-8,#9,0,-8,#10,0,-8)::GOTO MoJo_Loop
							
					MoJo_Shift:	IF IQ < SK*50 OR SK = 3 THEN MoJo_Loop		// No shift level 3 (easy)
						PC = INT(RND*30)-14::CALL MOTION(#7,0,PC)::IQ=0::GOTO MoJo_Loop
	
RETURN  //  ***************************************************************************************************


Brick_Ship: 	
				// Exit is fully bricked so toss LOL ship cage at paralyzed Ship
				// #4 = LOL ship cage, #5 = Ship, #7 = MoJo Pallet, #10 = Omega
		
		VR = INT(VR/3) :: VC = INT(VC/3)::CALL LINK("FREEZE"):: QS = QS - 200*(SM^2) ::GOSUB Update_Score
		
		CALL SOUND(500,131,5,132,6,133,7):: CALL SOUND(250,147,5,148,6,149,7):: CALL SOUND(375,156,5,157,6,158,7)
		CALL SOUND(500,131,5,132,6,133,7)
		FOR FI=1 TO 4 :: CALL SOUND(75,185,5,186,6):: CALL SOUND(75,175,5,176,6):: NEXT FI::CALL SOUND(-250,185,5,186,6,187,7)
		
		CALL MOTION(#5,0,0)::CALL POSITION(#5,DR,DC):: GR = INT((DR+7)/8):: GC = INT((DC+7)/8):: IF GR <23 THEN BS_Omega		//Ship
			GR = 23  // ship is not too close to bottom of screen
		BS_Omega: CALL POSITION(#10,PR,PC)::PR=PR+16:: PC = PC +4 :: IF PC <257 THEN Make_Brick2		//Omega
				PC = 256
			Make_Brick2: CALL SPRITE(#4,108,FC,PR,PC,(DR-PR)*49/100,(DC-PC)*49/100):: CALL LINK("THAW") 	// Flying Brick
				CALL SOUND(100,880,5,890,6):: CALL SOUND(100,880,10,660,11):: CALL SOUND(100,670,16,660,15)
			CALL MOTION(#4,0,0)::CALL DELSPRITE(#7):: DR=DR-1::DC=DC-2::CALL LOCATE(#4,DR,DC)
			FOR I = 1 TO 3 :: FOR J = 3 TO 16:: CALL COLOR(#4,J)::CALL LINK("DELAY",100)::NEXT J
			CALL SOUND(100,880,5,890,6):: CALL SOUND(100,880,10,660,11):: CALL SOUND(100,670,16,660,15):: NEXT I
	
			LM=LM - 1::HM=0::OS=0 :: OB = 0 :: CALL DELSPRITE(#4, #5,#6,#8,#9,#10)::IF LM > 0 Then Start_Over
				LM = 1
		GOTO Start_Over
		
RETURN


MoJo_Crash:  
		
			// Sprite 5 = Ship, 10 = Omega, 7 = VAST Mojo, 9 = Omega Beard, 8 = Omega Eyes, 6 = Engine Blast
			// Character 25 = Wall blocks
			
			CALL DELSPRITE(#6,#7,#8,#9,#10)::CALL MAGNIFY(1)::CALL LINK("CHAR2",25,"FFC3A59999A5C3FF"):: QS = QS - 200*(SM^2) // changes blocks to X-Blocks
			CALL LINK("FREEZE"):: CALL POSITION(#5,PR,PC)::CALL LINK("THAW")
			
			Crash_Motion: FOR I=33 TO 37 ::CALL MOTION(#5,(192-PR)*49/100, (128-PC)*49/100)::K = I*10::CALL PATTERN(#5,I)
				CALL SOUND(40,-8,0,110,5,698,10,K,0):: CALL LINK("FREEZE")::CALL POSITION(#5,PR,PC)::CALL LINK("THAW")::NEXT I
				CALL DISTANCE(#5,192,128,I):: IF I > 64 THEN Crash_Motion
				
				CALL DELSPRITE(#5)::CALL LINK("CHAR2",25,"7EA5C38181C3A57E")::LM=LM-1::HM=0::OS=0:: OB = 0 
				CALL LINK("DELAY",1000)::IF LM = 0 THEN Ender 
				CP = 1 ::GOSUB Update_Score  // reset crash penalty bit
			
RETURN			
	
MoJo_Drop:  // MF = Mojo Flag (mojo screen insturction flag), HM = Have Mojo Flag (has mojo and ready to drop)
			// CO = MoJo Hunt COinc, OF = Orbit Flag, C7 = Coinc with Sprite #7 flag, DF = Drop Failures
			// OS = Omega Struck? Flag, OD = Orbit Direction, DP = Droping Pallet Flag:: DI = Drop Instruction Flag
			
			
			CALL LINK("FREEZE"):: CALL PATTERN(#1,39) :: OD = 8 :: DP=0:: FU = 0 :: FR = 0 :: OB = 0::MS=0
			CALL LOCATE(#1,192,256)::CALL MAGNIFY(1)::CALL DELSPRITE(#5,#6, #8, #9, #10)::GOSUB Terrain_Paste
			
			
			IF HM = 0 THEN Rtn_Orbit  // else include MoJo pallet since Have MoJo True
				CALL PATTERN(#7,72)::CALL LOCATE(#7,17,PC)::CALL MOTION(#7,0,OD)
			
		Rtn_Orbit: CALL LOCATE(#1,9,PC)::CALL MOTION(#1,0,OD)::CALL LINK("THAW")::CALL LOCATE(#3,SR,SC)::GOSUB Sparky_Anim8

			CALL LINK("DELAY",1000):: IF HM=1 OR MF=1 THEN Orbit_Loop   // Already Have MoJo or Have Visited MoJo Hunt page previously
			
			// First time orbiter needs instructionssave 
				CALL LINK("VREAD",128,32,M$)::DISPLAY AT(5,7):"ORBIT ESTABLISHED"::CALL LINK("DELAY",1000)::CALL LINK("VWRITE",128,M$)
				// DISPLAY AT(5,2):"JOYSTICK L/R = ORBIT DIRECTION"::CALL LINK("DELAY",1000)::CALL LINK("VWRITE",128,M$)
				// DISPLAY AT(5,2):"JOYSTICK BUTTON TO DROP MOJO"::CALL LINK("DELAY",1000)::CALL LINK("VWRITE",128,M$)
				DISPLAY AT(5,2):"JOYSTICK UP TO BEGIN SEARCH"
			
				GOSUB Joystick_Up   
				
				CALL LINK("VWRITE",128,M$)::CALL MOTION(#1,0,0)::IF HM = 1 THEN  Orbit_Loop
				
				GOSUB MoJo_Hunt
			
			IF DI = 1 THEN Orbit_Loop
				CALL LINK("VREAD",128,128,M$):: DI = 1::DISPLAY AT(5,7):"MOJO READY FOR DROP"::CALL LINK("DELAY",1000)
				DISPLAY AT(5,4):"JOYSTICK BUTTON DROPS MOJO ":: CALL LINK("DELAY",2000):: CALL LINK("VWRITE",128, M$)
				
			Orbit_Loop: CALL LINK("THAW")		// FR is a scoring factor
				GOSUB Update_Score
				FR = FR +1::CALL JOYST(1,JC,JR):: IF JR = 4 AND HM = 0 THEN GOSUB MoJo_Hunt  // Joystick moved up
				CALL KEY(1,KV,SV)::IF ABS(SV) = 1 AND HM = 1 THEN Drop_Pallet  // 1 = pressed, 0 = no, -1 = held	
				
				IF DP = 1 THEN Drop_Pallet
				
				IF SV = 0 THEN Juke 
				
					CALL SOUND (50,210,1)
 
				Juke: IF JC = 0 THEN Orbit_Loop   // no switching directions
				  IF JC = 4 THEN Orbit_Rt
						IF JC = -4 THEN Orbit_Lt
						
			Orbit_Rt: OD = 8 :: FU=FU+1:: GOTO Chg_Dir
			Orbit_Lt: OD = -8 :: FU=FU+1
			
			Chg_Dir: CALL LINK("FREEZE"):: CALL MOTION(#1,0,OD,#7,0,OD):: GOTO Orbit_Loop  // OD = orbiter direction
				  
				  
			Drop_Pallet: 	// Code here to manage Mojo dropping and delivery to Sparkdrummer
				Free_Fall: 			// Up = JR = 4, Down = JR = -4, Left = JC = -4, Right = JC = 4, otherwise zeros
					CALL JOYST(1,JC,JR):: IF JC = 0 THEN Move_Pallet	// no steer input detected
					OD = JC ::FU = FU+5:: MS =MS+1::GOSUB Update_Score	// Pallet redirected from L/R or R/L, steer counted , impacts score
					
				Move_Pallet: CALL MOTION(#1,0,OD,#7,10,OD) :: HM = 0 :: DP = 1  // moves orbiter too
				
				
				CALL POSITION(#7,PR,PC)::CC=INT((PC+7)/8) :: CR=INT((PR+7)/8)::CALL GCHAR(CR,CC,C3):: CALL SOUND(-50,CR*100,10) 
				
				IF SR-PR > 16 THEN Test_Tile  	// Look for terrain collisions until MoJo approaches Sparkdrummer
					IF ABS(PC-SC+4) < 12-SK THEN MoJo_Delivered   // MoJo Landed within 10-8 pixels of middle of sparky
				
				Test_Tile: IF C3 = 24 OR C3 = 152 THEN Free_Fall // Still falling over blank tiles 

			MoJo_Drop_Fail:		
				
				DF=DF+1:: CALL MOTION(#1,0,OD,#7,0,0):: QS = QS - 100*(SM*2):: GOSUB Update_Score 	// DF drop failures impact score
				FOR I = 1 TO 3
				    CALL SOUND(100,1760,5,1770,6,1765,4):: CALL SOUND(200,880,3,890,4,885,5):: CALL SOUND(400,110,1,115,2,120,3)::NEXT I
					
				CALL DELSPRITE(#7) // remove MoJo pallet and reset Have/Found MoJo flags
				
				FOR I = 1 TO 3::CALL LINK("VREAD",128,32,M$)  // Copy Line 5
					DISPLAY AT(5,7):"MOJO DROP FAILURE"::CALL LINK("DELAY",500)::CALL SOUND(200,660,10)
					CALL LINK("VWRITE",128, M$) :: CALL LINK("DELAY", 200)::NEXT I
				
				FU = 0 :: FR = 0 :: DP = 0::DISPLAY AT(5,5):"JOYSTICK UP FIND MOJO"::GOSUB Joystick_Up
				CALL LINK("VWRITE",128,M$)::CALL MOTION(#1,0,0)::MF = 1:: GOTO MoJo_Hunt
				
				
				
			MoJo_Delivered: CALL MOTION(#1,0,0)::CALL LOCATE(#1,9,SC)	// stop orbiter above Sparky
				CALL SPRITE(#7,72,11,SR-8,SC,1,0)::CALL LINK("DELAY",2000)
				FOR I = 1 to 3::CALL SOUND(100,880,10,890,11):: CALL SOUND(200,440,4,450,5):: NEXT I::CALL DELSPRITE(#7)
				CALL COLOR(#3,11)  // Elevate Sparky based on screen level
				CALL PATTERN(#3,44)::CALL MOTION(#3,-15,0)::CALL LINK("DELAY",500*SL):: CALL MOTION(#3,0,0)
				CALL PATTERN(#3,45)::IF SL = 5 THEN Rendezvous
				CALL MOTION(#3,15,0)::CALL LINK("DELAY",500*SL)
				CALL MOTION(#3,0,0)::CALL POSITION(#3,SR,SC)::CALL PATTERN(#3,44)::CALL COLOR(#3,15)
				
				FOR I = 1 TO 3::CALL LINK("VREAD",128,32,M$)  
					DISPLAY AT(5,7):"MOJO DROP SUCCESS"::CALL LINK("DELAY",500)::CALL SOUND(100,880,10,890,11):: CALL SOUND(200,440,4,450,5)
					CALL LINK("VWRITE",128, M$) :: CALL LINK("DELAY", 200) :: NEXT I:: QS = QS+300*SM+150*SM*LM::GOSUB Update_Score
				// Score for delivery: 500,1000, or 1500 based on skill level
				// IF LM>2 AND SK = 3 THEN Joyful 	// hard level gives no more than three ships
				// IF LM>3 AND SK = 2	THEN Joyful	// mid level no moe than four ships
				// IF LM>4 THEN Joyful				// easy level can have five ships
				LM=LM+1		 
				Joyful: GOSUB Sparky_Anim8
				CALL MOTION(#1,0,0):: CALL LOCATE(#1,192,256)::CALL LOCATE(#3,192,256)::DP = 0
				DF = 0::MS = 0
				SL=SL+1:: IF SL=6 THEN Rendezvous 
				// Level 5 is Last Level = Winner
				
				// GOSUB Scoreboard
				
				IF SL = 5 THEN Quickest_Walls
				IF SL <> 4 THEN Start_Over
						TS = TS - TV ::GOTO Start_Over
					Quickest_Walls:
						TS = TS - TV::GOTO Start_Over
									
					
RETURN //  ****************************************************************************************************

Rendezvous:
		CALL LINK("FREEZE")::CALL LOCATE(#1,9,SC,#3,17,SC)::CALL MOTION(#1,0,10,#3,0,10)::CALL LINK("THAW")
		DISPLAY AT(5,9):"RENDEZVOUS!"::SL=6::CALL LINK("DELAY", 4250)
	
		Rdvz_Orbit: CALL DISTANCE(#1,9,256,I)::IF I > 25 THEN Rdvz_Orbit		// SQR(I) <25 = five dots away
		
		DISPLAY ERASE ALL::CALL HCHAR(24,1,25,32)
		To_Middle: CALL DISTANCE(#1,9,128,I):: IF I > 9 THEN To_Middle
		
		CALL LINK("FREEZE")::CALL POSITION(#1,PR,PC)::CALL LOCATE(#3,PR+8,PC)::CALL MOTION(#1,8,0,#3,8,0)::CALL LINK("THAW")
			
		Sparky_Down: CALL POSITION(#3,PR,PC):: IF PR < 177 THEN Sparky_Down	
		
		CALL LINK("FREEZE"):: CALL MOTION(#1,-6,0,#3,0,0)::CALL LINK("THAW")
		
		DISPLAY AT(2,5):"SPARKDRUMMER RESCUED!"::CALL LINK("DELAY",4250):: GOSUB Sparky_Anim8
		
		QS = QS + 3000 + LM*200*SM:: CALL HCHAR(24,23,25,6)	// clears bottom score field
		
		CALL MOTION(#1,0,4)::GOTO Win
		
		
RETURN

Ender:

		DISPLAY ERASE ALL :: CALL DELSPRITE(ALL):: CALL LINK("SCREEN",2)::DISPLAY AT(3,10):"GAME OVER"
		
		IF SL = 6 THEN Win ::DISPLAY AT(6,8):"RESCUE FAILED"
			Win: DISPLAY AT(9,9)SIZE(13):"SCORE  " & STR$(QS)
			
			IF HS >= QS THEN HScore ::HS = QS 
			
		HScore: DISPLAY AT(12,7)SIZE(16):"HIGH SCORE " & STR$(HS)
							
		Choices: DISPLAY AT(22,2):"UP TO REPLAY, DOWN TO QUIT"::CALL LINK("DELAY", 2000)
		Chk_Option: CALL JOYST(1,JC,JR)
			IF JR = -4 THEN Quitter
				GOSUB Ship_Swap	
			IF JC <> 4 THEN No_Credit

				DISPLAY AT(15,3):"THANK YOU ATARIAGE 99ERS:"
				DISPLAY AT(17,1):"MATTHEW180,SHIFT838,THECODEX"
				DISPLAY AT(19,1):"RALPHB,F.G.KAAL,ASMUSR,OMEGA"
				
		No_Credit: IF JR = 0 THEN Chk_Option
						CALL DELSPRITE(ALL)::GOTO SCRAA
		Quitter: DISPLAY ERASE ALL::END		// End Program
RETURN

//  ----------------------------------------------------------------------------------------------------------

			
// Data storage for level colors and character definitions (5)
	DATA 8,3,6,15,7    // Level border colors
		
		// ********** SCREEN2 characters (18) **********************************************************
		
		// Blank Black Tile 24, Building Block Red 25, BBR2 26, BBR3 27,Red Ship 28
	DATA 24,0000000000000000,25,7EA5C38181C3A57E,26,7E8199A5A599837E,27,7E8181999981817E, 28,183C72623C187EC3
		
		// Breadcrumb (152), Yellow Rt Arrow (153), Yellow Down Arrow( 154)
	DATA 152,000000000040A040,153,00080CFEFE0C0800,154,181818187E3C1800
		
		// Airshack Logo
	DATA 248,03070D193F61C181,249,010141115C545151
	DATA 250,E02008E8282E2AEA,251,00000000619292F9,252,00001010D41814D2
	
		// Terrain Characters (4): Block/Flat (160), Peak(161), TLBR(162), BLTR(163), Cactus(144),
		
	DATA 160, "EFBDF6BF55EFBADF", 161, "181C342E3A6E7BDD", 162, "80C0C0F8BCF4AEFB", 163, "01030207051E7BD7", 144,"00181A5A5E781818"
		
		
		// ********** SCREEN1 characters (24)-- Sprites require SCRN1 Patterns
		
		// 4 Character Sprites (11)
		
		// Ship Mega (four characters)
 	DATA 120, "183C42423C187EC3000000000000000000000000000000000000000000000000"
		// MoJo Pallet (four characters)
	DATA 124, "0000000000000000FF81A39589C1213F00000000000000000000000000000000"
		// TI Omega Mega
	DATA 104, "00071F3870604E44446030180C7C7C0000E0F81C0E06722272060C18303E3E00"
		// LOL Ship Cage
	DATA 108, "FFF9F0E0E0F0F9E0CFFFFF008F8989EFF0F0F07070F0F07030F0F30343434073"
		// Omega Beard - Mean/Bad
	DATA 128, "000000381E87818080000006030301000000000E3C7141010100003060E0C08"
		// Omega Eyes
	DATA 136, "00000000000E1F1C1F0E00000004047C0000000000387C707C3800000001011F"
		// MoJo VAST Mega
	DATA 68,  "1F1010106747472311102020300C0300FF0101011D1D1DB9F1E14101010101FF"
		// Engine Blast 4 chars
	DATA 140, "0000000000000000381000281000000000000000000000000000000000000000"
		// Omega Brick 4 Chars
	DATA 132, "7EA5C38181C3A57E000000000000000000000000000000000000000000000000"
		// Festwest 2017 Logo
	DATA 112, "EE88EE888E008B8AABDA8B2053344473EE84E424E400B722BA0ABA002EA2A424"
		
		// VAST Mojo Pallet (single character)  (1)
	DATA 72, "FF81A39589C1213F"
	
		
		
		// Sparkdrummer DrumRoller + Jump Up and Fall Down (6)
		
	DATA 40,001C182A49FF0C1A,41,225D9808493E0C1A,42,77001C180A7E0C1A,43,41221C18493E0C1A,44,38301038D6929228,45,BA9A925438101028
		    
		
		// Ship1-Ship5, Engine Flame, Orbit Ship(7)
	DATA 33,183C72623C187EC3,34,183C5A723C187EC3,35,183C4E5A3C187EC3,36,183C464E3C187EC3,37,183C62463C187EC3,38,3810002810000000
	DATA 39,183C42423C187EC3
	
		
		
	